<template>
  <el-upload
    :limit="4"
    list-type="picture-card"
    ref="upload"
    name="uploadFile"
    :file-list="imgList"
    :on-success="_uploadSuccess"
    :on-exceed="_handleExceed"
    :on-error="_uploadError"
    :on-remove="_uploadChange"
    :on-change="_uploadChange"
    :before-upload="_beforeUpload"
    :action="uploadUrl">
    <i class="el-icon-plus"></i>
  </el-upload>
</template>

<script>
import { uploadUrl } from '@/services/model/common'
export default {
  props: ['value'],
  computed: {
    imgList: {
      get () {
        return this.value
      },
      set (value) {
        this.$emit('input', value)
      }
    }
  },
  data () {
    return {
      uploadUrl
    }
  },
  methods: {
    // 添加文件个数限制
    _handleExceed (files, fileList) {
      // 每次只能提交一个文件
      if (this.imgList?.length >= 4) {
        this.$message.warning('最多添加4张照片')
        return false
      }
    },
    /**
     * 上传文件之前的钩子，参数为上传的文件
     * 若返回 false 或者返回 Promise 且被 reject，则停止上传。
     */
    _beforeUpload (file) {
      // 文件类型
      const FILE_TYPE = file.type
      // 文件大小
      const FILE_SIZE = Number(file.size || 0)
      // 允许上传的图片的类型
      const ALLOW_LIST = ['image/jpeg', 'image/png']
      // 4M限制
      const FILE_SIZE_LIMIT = 1024 * 1024 * 4
      if (!ALLOW_LIST.includes(FILE_TYPE) || FILE_SIZE > FILE_SIZE_LIMIT) {
        // 文件类型不符提示信息
        const TYPE_INFO = '只能上传图片'
        // 文件大小超出限制提示信息
        const TYPE_SIZE = '文件大小限制4M以内'
        const INFO_MSG = !ALLOW_LIST.includes(FILE_TYPE) ? TYPE_INFO : TYPE_SIZE
        this.$message.error(INFO_MSG)
        return false
      }
    },
    // 上传错误
    _uploadError (err) {
      this.$message.error('上传失败:' + err)
    },
    // 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
    _uploadChange (file, fileList) {
      this.imgList = fileList
    },
    /**
     * 文件上传成功时的钩子
     */
    _uploadSuccess (res, file, fileList) {
      if (res.code === 200) {
        this.$message.success('图片已上传')
      } else {
        this.$message.error(res.message)
      }
    },
  } 
}
</script>

<style>

</style>